package tech.yunqian.slim.framework.web;

import java.io.IOException;

import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jackson.JsonLoader;
import com.github.fge.jsonschema.core.exceptions.ProcessingException;
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.github.fge.jsonschema.main.JsonSchema;
import com.github.fge.jsonschema.main.JsonSchemaFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class RequestValidator {
    private Logger log = LoggerFactory.getLogger(RequestValidator.class);

    String base = "/schema";

    public static final int CODE_FAIL = 0;
    public static final int CODE_PASS = 1;
    public static final int CODE_SCHEMA_NOT_LOADED = 2;
    public static final int CODE_SCHEMA_PROCESSING_ERROR = 3;

    public int validate(String schema, String request) {
        int code = CODE_FAIL;
        final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
        JsonNode schemaNode;
        JsonNode requestNode;
        JsonSchema instance;
        try {
            schemaNode = JsonLoader.fromResource(base + schema);
        } catch (IOException e) {
            log.info(e.getMessage());
            code = CODE_SCHEMA_NOT_LOADED;
            return code;
        }
        try {
            log.debug("{}", request);
            requestNode = JsonLoader.fromString(request);
            instance = factory.getJsonSchema(schemaNode);
            ProcessingReport report = instance.validate(requestNode);
            if (report.isSuccess()) {
                code = CODE_PASS;
            } else {
                log.debug(report.toString());
            }
        } catch (IOException e) {
            log.info(e.getMessage());
            code = CODE_SCHEMA_PROCESSING_ERROR;
        } catch (ProcessingException e) {
            log.info(e.getMessage());
            code = CODE_SCHEMA_PROCESSING_ERROR;
        }
        return code;
    }
}